﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IntroMVC4.Models.Domain;
using IntroMVC4.Models.Interface;

namespace IntroMVC4.Models.Services
{
    public class ProductService : IProduct, IDisposable
    {
        private ProductModelEntities context;

        public ProductService()
        {
            this.context = new ProductModelEntities();
        }
        public ProductService(ProductModelEntities context)
        {
            this.context = context;
        }
        #region INPUT FROM
        public IList<ListInputFrom> GetAllInputForms()
        {
            var query = (from p in context.InputForms
                         join w in context.Websites on p.WebsiteId equals w.Id
                         select new ListInputFrom { 
                            Id=p.Id,
                            DateEdit = p.DateEdit,
                            DateInput=p.DateInput,
                            ProductsPrice=p.ProductsPrice,
                            ShipPrice=p.ShipPrice,
                            TotalAmount=p.TotalAmount,
                            UserEdit=p.UserEdit,
                            UserInput=p.UserInput,
                            WebsiteId=p.WebsiteId,
                            WebsiteUrl = w.Url
                         }).ToList();
            return query;
        }
        #endregion
        #region IProduct Members

        public IList<ProductD> GetAllProducts()
        {
            return null;
            //var query = (from p in context.Products.Include("PrincipalCategory")
            //             select p).Distinct().ToList();
            //List<ProductD> result = (from p in query
            //                         group p by p.SKU into g
            //                         select new ProductD
            //             {
            //                 Name = g.Select(a => a.Name).FirstOrDefault(),
            //                 Quantity = g.Sum(a => a.Quantity),
            //                 SKU = g.Key.ToString(),
            //                 PrincipalName = g.Select(a => a.PrincipalCategory.Name).FirstOrDefault(),
            //                 GTIN = g.Select(a => a.GTIN).FirstOrDefault(),
            //                 IsActive = g.Select(a => a.IsActive).FirstOrDefault()
            //             }).ToList();
            //return result;
        }

        public IList<ProductD> GetFilterProducts(string productName)
        {
            return null;
            //var query = (from p in context.Products
            //             where p.Name.Contains(productName)
            //             select new ProductD
            //             {
            //                 Name = p.Name,
            //                 Quantity = p.Quantity,
            //                 SKU = p.SKU,
            //                 PrincipalName = p.PrincipalCategory.Name
            //             });
            //return query.Distinct().ToList();
        }
        public IEnumerable<PrincipalCategory> GetPrincipalCategories()
        {
            return context.PrincipalCategories;
        }
        public IEnumerable<ProductCategory> GetProductCategories()
        {
            return context.ProductCategories;
        }
        public ProductSKU GetProductBySKU(string sku)
        {
            return null;
            //var query = (from p in context.Products
            //             where p.SKU.Contains(sku)
            //             select p).Distinct().ToList();
            //int? ProductCatalogId = null;
            //List<AttributeProductD> listAttrPro = GetAttributeProductsByProductIds(query.Select(p => p.Id).ToArray(), out ProductCatalogId);
            //var firstId = query.Select(p => p.Id).FirstOrDefault();
            //List<AttributeProductD> listAttrProTemp = listAttrPro.Where(a => a.ProductId == firstId).ToList();
            //return (from p in query
            //        group p by p.SKU into g
            //        select new ProductSKU
            //            {
            //                ListAttributeProductD = listAttrPro,
            //                Name = g.Select(a => a.Name).FirstOrDefault(),
            //                Quantity = g.Sum(a => a.Quantity),
            //                SKU = g.Key.ToString(),
            //                PrincipalCategoryId = g.Select(a => a.PrincipalCategoryId).FirstOrDefault(),
            //                GTIN = g.Select(a => a.GTIN).FirstOrDefault(),
            //                IsActive = g.Select(a => a.IsActive).FirstOrDefault(),
            //                ProductCatalogId = ProductCatalogId
            //            }).FirstOrDefault();
        }
        public List<AttributeProductD> GetAttributeProductsByProductIds(long[] productIds, out int? productCatalogId)
        {
            List<AttributeProductD> listAttrPro = new List<AttributeProductD>();
            var query = (from ap in context.AttributeProducts
                         join a in context.Attributes on ap.AttributeId equals a.Id
                         where productIds.Contains(ap.ProductId)
                         orderby a.Name
                         select new AttributeProductA
                         {
                             ProductId = ap.ProductId,
                             Name = a.Name,
                             Value = ap.Value,
                             ProductCategoryId = a.ProductCategoryId
                         }).ToList();
            productCatalogId = query.Select(a => a.ProductCategoryId).FirstOrDefault();
            for (int i = 0; i < productIds.Length; i++)
            {
                listAttrPro.Add(new AttributeProductD
                {
                    ListAttributeProduct = query.Where(p => p.ProductId == productIds[i]).ToList(),
                    ProductId = productIds[i]
                });
            }
            return listAttrPro;
        }
        public AttributeProductD GetAttributeProductByProductId(long productId)
        {
            var query = (from ap in context.AttributeProducts
                         join a in context.Attributes on ap.AttributeId equals a.Id
                         where ap.ProductId == productId
                         select new AttributeProductA
                         {
                             Name = a.Name,
                             Value = ap.Value,
                         }).ToList();
            return new AttributeProductD
            {
                ListAttributeProduct = query,
                ProductId = productId
            };
        }
        public List<Attribute> GetListAttributeByProductCatagory(int productCatagoryId)
        {
            return context.Attributes.Where(a => a.ProductCategoryId == productCatagoryId).Select(a => a).ToList();
        }
        public bool AddProduct(string sku, string gtin, string name, int principalCategoryId, bool isActive, int productCatalogId)
        {
            //try
            //{
            //    Product objProduct = new Product
            //            {
            //                Id = Guid.NewGuid(),
            //                SKU = sku,
            //                GTIN = gtin,
            //                Name = name,
            //                PrincipalCategoryId = principalCategoryId,
            //                Quantity = 0,
            //                CreatedDate = DateTime.Now
            //            };
            //    context.Products.Add(objProduct);
            //    List<IntroMVC4.Models.Attribute> listAttr = GetListAttributeByProductCatagory(productCatalogId);
            //    foreach (IntroMVC4.Models.Attribute param in listAttr)
            //    {
            //        AttributeProduct attrProduct = new AttributeProduct
            //        {
            //            Id = Guid.NewGuid(),
            //            AttributeId = param.Id,
            //            Value = "",
            //            ProductId = objProduct.Id
            //        };
            //        context.AttributeProducts.Add(attrProduct);
            //    }
            //    context.SaveChanges();
                return true;
            //}
            //catch (Exception ex)
            //{
            //    //throw ex;
            //    return false;
            //}
        }
        public bool UpdateProduct(string sku, string gtin, string name, int principalCategoryId, bool isActive, string productIds, string attParams)
        {
            //try
            //{
            //    List<Product> listProduct = (from p in context.Products//.Include("AttributeProducts")
            //                                 where p.SKU == sku
            //                                 select p).ToList();
            //    string[] listParams = attParams.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
            //    //"1=L,S,XX;
            //    //2=Red,Red,Blue;
            //    //3=5,4,4;"
            //    string[] listProductParams = productIds.Split(new string[] { "," }, StringSplitOptions.None);
            //    List<AttributeProduct> AttributeProductsDelete = new List<AttributeProduct>();
            //    foreach (var product in listProduct)
            //    {
            //        product.GTIN = gtin;
            //        product.Name = name;
            //        product.PrincipalCategoryId = principalCategoryId;
            //        product.Quantity = 0;
            //        product.UpdatedDate = DateTime.Now;
            //        foreach (var item in product.AttributeProducts)
            //            AttributeProductsDelete.Add(item);
            //    }
            //    List<Guid> listProductParamsI = new List<Guid>();
            //    foreach (var productParam in listProductParams)
            //    {
            //        if (productParam == "0")
            //        {
            //            Product objProduct = new Product
            //            {
            //                Id = Guid.NewGuid(),
            //                SKU = sku,
            //                GTIN = gtin,
            //                Name = name,
            //                PrincipalCategoryId = principalCategoryId,
            //                Quantity = 0,
            //                CreatedDate = DateTime.Now
            //            };
            //            context.Products.Add(objProduct);
            //            //listProductParamsI.Add(objProduct.Id);
            //            listProduct.Add(objProduct);
            //        }
            //        //else
            //        //    listProductParamsI.Add(new Guid(productParam));
            //    }
            //    //Attribute Product
            //    //int index = Array.IndexOf(listProductParams, product.Id.ToString());
            //    //string[] listAttribute = listParams[index];
            //    List<AttributeProduct> listAttrProduct = new List<AttributeProduct>();
            //    for (int i = 0; i < listParams.Length; i++)
            //    {
            //        var attrTemps = listParams[i].Split(new string[] { "=" }, StringSplitOptions.None);
            //        int ipro = 0;
            //        foreach (var product in listProduct)
            //        {
            //            var attrValues = attrTemps[1].Split(new string[] { "," }, StringSplitOptions.None);
            //            if (Convert.ToInt64(attrTemps[0]) == 3)//Quantity
            //                product.Quantity += Convert.ToInt32(attrValues[ipro]);
            //            AttributeProduct attrProduct = new AttributeProduct
            //                {
            //                    Id = Guid.NewGuid(),
            //                    AttributeId = Convert.ToInt64(attrTemps[0]),
            //                    Value = attrValues[ipro],
            //                    ProductId = product.Id
            //                };
            //            context.AttributeProducts.Add(attrProduct);
            //            ipro++;
            //        }
            //    }
            //    foreach (var itemDel in AttributeProductsDelete)
            //        context.AttributeProducts.Remove(itemDel);
            //    context.SaveChanges();
                return true;
            //}
            //catch (Exception ex)
            //{
            //    //throw ex;
            //    return false;
            //}
        }
        #endregion

        #region IDisposable Members
        private bool disposed = false;
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    context.Dispose();
                }
            }
            this.disposed = true;
        }
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        #endregion
    }
}